package edu.gmu.projects.fireresponder.environment;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Route extends Asset {
	public static final int DEFAULT_SPEED = 10;  // kilometers / hour; 10 = very fast walk pace
	private double distance;
	private static int routeCounter = 0;

	private List<Path> route;

	public Route() {
		routeCounter ++;
		String s = String.format("Route %4d", routeCounter);
		setId(s);
		route = new ArrayList<Path>();
	}

	public List<Path> getPaths() {
		return route;
	}

	public void setPaths(List<Path> paths) {
		this.route = paths;
		updateDistance();
	}

	public void addPaths(Path path) {
		this.route.add(path);
		updateDistance();
	}

	public void addPaths(List<Path> paths) {
		this.route.addAll(paths);
		updateDistance();
	}

	private void updateDistance() {
		distance = 0;
		if(isValid()) {
			for(Path p : route) {
				distance += p.getDistance();
			}
		} else {
			distance = Double.MAX_VALUE;
		}
	}

	public Location getStart() {
		if (route.size() == 0) {
			return null;
		} else if (route.size() == 1) {
			return route.get(0).getP1();
		} else {
			Path first = route.get(0);
			Path second = route.get(1);
			if (second.getPoints().contains(first.getP1())) {
				return first.getP2();
			} else {
				return first.getP1();
			}
		}
	}

	public int getDistance() {
		int distance = 0;
		for (Path p : route) {
			distance += p.getDistance();
		}

		return distance;
	}

	public Location getEnd() {
		if (route.size() == 0) {
			return null;
		} else if (route.size() == 1) {
			return route.get(0).getP2();
		} else {
			Path last = route.get(route.size() - 1);
			Path secondToLast = route.get(route.size() - 2);
			if (secondToLast.getPoints().contains(last.getP1())) {
				return last.getP2();
			} else {
				return last.getP1();
			}
		}
	}

	public boolean isValid() {
		for (int i = 0; i < route.size() - 1; i++) {
			if (!route.get(i).intersects(route.get(i + 1))) {
				return false;
			}
		}
		return true;
	}

	@Override
	public int getEstimatedTimeToComplete() {
		return getEstimatedTimeToComplete(DEFAULT_SPEED);
	}

	public int getEstimatedTimeToComplete(double kmperhour) {
		return (int) (distance * 3600 / kmperhour);
	}

	@Override
	public int compareTo(Asset o) {
		// Route r = (Route)o;
		return 0;
	}

	@Override
	public Set<Location> getPoints() {
		Set<Location> points = new HashSet<Location>();

		for (Path p : route) {
			points.addAll(p.getPoints());
		}

		return points;
	}

	@Override
	public Location getCenter() {
		if (route.size() == 0)
			return null;
		
		int middlePath = route.size() / 2;
		return route.get(middlePath).getCenter();
	}

	public Collection<Asset> getConnectedAssets() {
		// not implemented
		return null;
	}
	
	public String toString() {
		return Arrays.toString((Path[]) route.toArray(new Path[0]));
	}

}